package com.songcha.sakura.util

import android.content.ContentUris
import android.content.ContentValues
import android.content.Context
import android.database.Cursor
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.MediaStore
import androidx.annotation.RequiresApi
import com.bumptech.glide.Glide
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Target
import java.io.*
import java.net.HttpURLConnection
import java.net.URL


class FileUtil {
    companion object{

        fun delete(path:String){
            val file=File(path)
            if(file.exists())
                file.delete()
        }

        //删除文件夹
        fun deleteDirWithFile(dir: File){
            if (dir == null || !dir.exists() || !dir.isDirectory)
                return

            val files=dir.listFiles()
            if(files==null) return
            for (file in files) {
                if (file.isFile)
                    file.delete() // 删除所有文件

                else if (file.isDirectory)

                    deleteDirWithFile(file) // 递归的方式删除文件夹

            }

            dir.delete()// 删除目录本身
        }

        fun isDirExist(file:File):Boolean{
            return file.exists() && file.isDirectory
        }

        fun isDirExist(path:String):Boolean{
            val file=File(path)
            return file.exists() && file.isDirectory
        }

        fun mkDir(path:String):Boolean{
            val file=File(path)
            if(!file.exists())
                return file.mkdir()
            else
                return false
        }

        fun downloadImage(context: Context,url:String,path:String){
            Glide.with(context)
                .downloadOnly()
                .load(url)
                .listener(object : RequestListener<File> {
                    override fun onLoadFailed(
                        e: GlideException?,
                        model: Any?,
                        target: Target<File>?,
                        isFirstResource: Boolean
                    ): Boolean {
                        return false
                    }

                    @RequiresApi(Build.VERSION_CODES.Q)
                    override fun onResourceReady(
                        resource: File?,
                        model: Any?,
                        target: Target<File>?,
                        dataSource: DataSource?,
                        isFirstResource: Boolean
                    ): Boolean {
                        resource?.let{
                          copyfile(it,File(path))
                        }

                        return false
                    }

                })
                .preload()

        }

        fun copyfile(fromFile:File, toFile:File):Boolean{
            if(!fromFile.exists()){
                return false
            }
            if(!fromFile.isFile()){
                return false
            }
            if(!fromFile.canRead()){
                return false
            }
            if(!toFile.getParentFile().exists()){
                toFile.getParentFile().mkdirs()
            }
            if(toFile.exists()){
                toFile.delete()
            }
            var fis:FileInputStream?=null
            var fos:FileOutputStream?=null
            try {
                fis =  FileInputStream(fromFile)
                fos =  FileOutputStream(toFile)

                val bt=ByteArray(1024)

                var c=fis.read(bt)
                while (c>0){
                    fos.write(bt,0,c)
                    c=fis.read(bt)
                }

            } catch (e: FileNotFoundException) {
                e.printStackTrace()
                return false
            } catch (e:IOException) {
                e.printStackTrace()
                return false
            }finally {
                fos?.flush()
                //关闭输入、输出流
                fis?.close()
                fos?.close()
            }
            return true
        }

        //公共目录查询目录
        @JvmStatic
        private fun searchImageFromPublic(context:Context, filePath:String, fileName:String):Cursor? {
            if (fileName.isNotEmpty()) {
                return null
            }
            var fp=filePath
            if (fp.isNotEmpty()) {
                fp = "DCIM/"
            } else {
                if (!fp.endsWith("/")) {
                    fp = fp + "/"
                }
            }

            //兼容androidQ和以下版本
            val queryPathKey = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)  MediaStore.Images.Media.RELATIVE_PATH else MediaStore.Images.Media.DATA
            val selection = queryPathKey + "=? and " + MediaStore.Images.Media.DISPLAY_NAME + "=?"
            val cursor = context.contentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                arrayOf(MediaStore.Images.Media._ID, queryPathKey, MediaStore.Images.Media.MIME_TYPE, MediaStore.Images.Media.DISPLAY_NAME),
                selection,
                arrayOf(fp,fileName),
                null)
            return cursor
        }


        //android10存储文件到公有目录
        @JvmStatic
        fun copyImage2Public(context:Context, fileName:String, image:ByteArray,  subDir:String) {
            var subDirection=""
            if (subDir.isNotEmpty()) {
                if (subDir.endsWith("/")) {
                    subDirection = subDir.substring(0, subDir.length - 1)
                } else {
                    subDirection = subDir
                }
            } else {
                subDirection = "DCIM"
            }

            val cursor = searchImageFromPublic(context, subDir, fileName)
            if (cursor != null && cursor.moveToFirst()) {
                try {
                    var cId=cursor.getColumnIndex(MediaStore.Images.Media._ID)
                    if(cId<0) return
                    val id = cursor.getInt(cId) // uri的id，用于获取图片
                    val uri = Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "" + id)
                    val contentUri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id.toLong())
                    if (uri != null) {
                        val outputStream = context.contentResolver.openOutputStream(uri)
                        if (outputStream != null) {
                            outputStream.write(image)
                            outputStream.flush()
                            outputStream.close()
                        }
                    }
                    return
                } catch (e:IOException) {
                    e.printStackTrace()
                }
            }

            try {
                //设置保存参数到ContentValues中
                val contentValues =  ContentValues()
                //设置文件名
                contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, fileName)
                //兼容Android Q和以下版本
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                    //android Q中不再使用DATA字段，而用RELATIVE_PATH代替
                    //RELATIVE_PATH是相对路径不是绝对路径
                    //关于系统文件夹可以到系统自带的文件管理器中查看，不可以写没存在的名字
                    contentValues.put(MediaStore.Images.Media.RELATIVE_PATH, subDirection)
                    //contentValues.put(MediaStore.Images.Media.RELATIVE_PATH, "Music/sample");
                } else {
                    contentValues.put(MediaStore.Images.Media.DATA, Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getPath())
                }
                //设置文件类型
                contentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/JPEG")
                //执行insert操作，向系统文件夹中添加文件
                //EXTERNAL_CONTENT_URI代表外部存储器，该值不变
                val uri = context.contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
                if (uri != null) {
                    //若生成了uri，则表示该文件添加成功
                    //使用流将内容写入该uri中即可
                    val outputStream = context.contentResolver.openOutputStream(uri)
                    if (outputStream != null) {
                        outputStream.write(image)
                        outputStream.flush()
                        outputStream.close()
                    }
                }
            } catch (e:IOException) {
                e.printStackTrace()
            }
        }


        fun saveNetFile(file:File,url:String):Int{
            val url= URL(url)
            val urlConnection=url.openConnection() as HttpURLConnection
            urlConnection.connect()

            var fis:InputStream?=null
            var fos:FileOutputStream?=null
            val buf=ByteArray(1024)
            var size=0

            try{
                fis=urlConnection.inputStream
                fos=FileOutputStream(file)
                var c=0
                c=fis.read(buf)
                size+=c
                while (c>-1 ){
                    fos.write(buf,0,c)
                    c=fis.read(buf)
                    size+=c
                }

            }catch (e:IOException){
                e.printStackTrace()
            }finally {
                fos?.flush()
                fos?.close()
            }

            return size

        }

        fun writeBytes(file:File,bytes:ByteArray){

            var fis:ByteArrayInputStream?=null
            var fos:FileOutputStream?=null

            val buf=ByteArray(1024)

            try{
                fis=ByteArrayInputStream(bytes)
                fos=FileOutputStream(file)
                var c=0
                while (fis.read(buf).also{
                        c=it
                    }>-1) {
                    fos.write(buf,0,c)
                }
            }catch (e:Exception){
                e.printStackTrace()
            }finally {
                fos?.flush()
                fos?.close()
            }

        }

        fun writeStr(file:File,str:String){
           // if(!file.exists()) file.createNewFile()
            try{
               val fw=FileWriter(file)
               fw.write(str)
               fw.flush()
               fw.close()
            }catch (e:Exception){
               e.printStackTrace()
            }
        }


        fun readContent(path:String,block:((line:String)->Unit)?=null):String{
            val file=File(path)
            if(!file.exists()) return ""

            val fis=file.inputStream()

            val reader = BufferedReader(InputStreamReader(fis, "utf-8"))

            val sb = StringBuffer()
            var temp:String?=""


            while (reader.readLine().also {
                    if(it!=null)
                        temp = it
                } != null) {

                block?.let {
                    it(temp?:"")
                }
                sb.append(temp)
                sb.append("\n")
            }

            var str=sb.toString()
            if(str.length>0)
                str=str.substring(0,str.length-1)
            return str
        }




    }

}